home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / admin / chklost < prev    next >
Encoding:
Korn shell script  |  1997-08-26  |  4.9 KB  |  165 lines

  1. #!/bin/ksh
  2. # @(#) chklost.ksh 2.0 95/10/22
  3. # 90/10/29 john h. dubois iii (john@armory.com)
  4. # 91/03/09 fixed bug which prevented chklost from being able to do 'file'
  5. #       on files from more than one dir (do a final read from coprocess
  6. #       so that coprocess pipe will be closed, so it can be opened again)
  7. # 91/03/19 added check to determine whether filesystem name and mount dir
  8. #       are swapped as under UNIX, and switch them if so
  9. # 93/02/06 Added -v option
  10. # 95/10/22 Cleaned up, made more robust, added ability to spec fs names on
  11. #          command line, added hrRt options.
  12.  
  13. typeset -i verbose=0
  14.  
  15. alias istrue="test 0 -ne"
  16. alias isfalse="test 0 -eq"
  17.  
  18. name=${0##*/}
  19. Usage="Usage: $name [-hrtv] [-R<pattern>] [filesystem ...]"
  20. remove=false
  21. removePat='ksh history file'
  22. tell=false
  23.  
  24. while getopts :hvrtR: opt; do
  25.     case $opt in
  26.     h)
  27.     echo \
  28. "$name: check lost+found directories for files reconnected by fsck.
  29. $Usage
  30. The number of files found in the lost+found directory each filesystem is
  31. printed, followed by a long listing of the inode data for each file and what
  32. /bin/file thinks the file contains.  If no filesystem names are given, all
  33. mounted filesystems (as reported by mount(ADM)) are checked.  $name can only
  34. check mounted filesystems.  The device or mount point for a filesystem may be
  35. given.
  36. Options:
  37. -h: Print this help.
  38. -r: Remove certain files from the lost+found directories that are examined,
  39.     based on what file(C) reports.  Removed files are those for which file(C)
  40.     reports 'ksh history file'.
  41. -R<pattern>: Remove any files from the lost+found directories that are examined
  42.     whose type as reported by file(C) matches <pattern>.  <pattern> may be a
  43.     ksh pattern, e.g. '@(ksh history file|SecureWare ttys database)'.  If a
  44.     pattern or a string contain whitespace is given, it should be quoted to
  45.     protect it from the shell.
  46. -t: Used in conjunction with -r or -R.  Tell which files would be removed,
  47.     but do not remove them.
  48. -v: Report filesystems that have no lost files or no lost+found directory."
  49.     exit 0
  50.     ;;
  51.      v)
  52.     verbose=1
  53.     ;;
  54.     t)
  55.     tell=true
  56.     ;;
  57.     r)
  58.     remove=true
  59.     ;;
  60.     R)
  61.     removePat=$OPTARG
  62.     remove=true
  63.     ;;
  64.     +?)
  65.     print -u2 "$name: options should not be preceded by a '+'."
  66.     exit 1
  67.     ;;
  68.     :)
  69.         print -r -u2 -- \
  70.         "$name: Option '$OPTARG' requires a value.  Use -h for help."
  71.         exit 1
  72.         ;;
  73.     ?)
  74.     print -u2 "$name: $OPTARG: bad option.  Use -h for help."
  75.     exit 1
  76.     ;;
  77.     esac
  78. done
  79.  
  80. # remove args that were options
  81. let OPTIND=OPTIND-1
  82. shift $OPTIND
  83.  
  84. # Usage: CheckFS filesys mountdir
  85. function CheckFS {
  86.     typeset filesys=$1 mountdir=$2 tm lfdir file fileno description
  87.  
  88.     if [[ $mountdir = /dev/* ]]; then    # if swapped, swap them back
  89.     tm=$filesys
  90.     filesys=$mountdir
  91.     mountdir=$tm
  92.     fi
  93.     lfdir="${mountdir%/}/lost+found"    # find lost+found dir for filesystem
  94.     # change to lost+found dir if it exists; 
  95.     # otherwise continue with next filesystem
  96.     if [ ! -d "$lfdir" ]; then
  97.     istrue verbose && print -ru2 -- "$mountdir has no lost+found directory."
  98.     return 1
  99.     fi
  100.     cd "$lfdir" || {
  101.     print -ru2 "Could not cd to $mountdir"
  102.     return 1
  103.     }
  104.     set -- *
  105.     if [ "$1" = "*" ]; then
  106.     istrue verbose && print -ru2 -- "$filesys: no files in $lfdir."
  107.     return 0
  108.     fi
  109.     print -n -- "$filesys: $# files found in $lfdir"
  110.     if $remove; then
  111.     if $tell; then
  112.         print "; would remove:"
  113.     else
  114.         print "; removing:"
  115.     fi
  116.     else
  117.     print ""
  118.     fi
  119.     # start up /bin/file as a coprocess, 
  120.     # so its output can be read along with the output of l
  121.     /bin/file "$@" |&
  122.     # use -d to make sure l lists only the files matched by *,
  123.     # so its output lines will sync with /bin/file *
  124.     l -d -- "$@" | while read file; do
  125.     # read from /bin/file
  126.     read -p fileno description
  127.     fileno=${fileno%:}
  128.     # in case something funny happens
  129.     if [[ "$file" != *"$fileno" ]]; then
  130.         print -u2 "l and file out of sync."
  131.         return 1
  132.     fi
  133.     if $remove; then
  134.         # Must eval to match extended ksh patterns.  But, that causes
  135.         # simple patterns that contain spaces to be split.  Can't quote
  136.         # pattern because extended patterns are protected from being
  137.         # recognized as patterns by quotes.  So, make all expressions be
  138.         # extended patterns by putting @() around them.
  139.         if eval [[ \"\$description\" = "@($removePat)" ]]; then
  140.         print -r -- "$file  $description"
  141.         $tell || rm -- "$fileno"
  142.         fi
  143.     else
  144.         print -r -- "$file  $description"
  145.     fi
  146.     done 
  147.     # read from coprocess again so its pipe will be closed
  148.     read -p
  149.     return 0
  150. }
  151.  
  152. if [ $# -eq 0 ]; then
  153.     # for each filesystem listed by mount...
  154.     /etc/mount | while read filesys on mountdir date; do
  155.     CheckFS "$filesys" "$mountdir"
  156.     done
  157. else
  158.     for fsName; do
  159.     [[ "$fsName" != */* ]] && fsName=/dev/$fsName
  160.     mount | egrep "(^| )$fsName " | read filesys on mountdir date &&
  161.     CheckFS "$filesys" "$mountdir" || 
  162.     print -u2 -- "$fsName: no such filesystem, or filesystem not mounted."
  163.     done
  164. fi
  165.